package com.notebook.aspect;

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.notebook.annotation.YCacheAnno;
import com.notebook.util.EhcacheUtils;

@Aspect
@Component
public class YCacheAop {
	private  static  final Logger logger = LoggerFactory.getLogger(YCacheAop.class);
    @Pointcut("@annotation(com.notebook.annotation.YCacheAnno)")  
    public void methodCachePointcut(){    
    }  
      
    @Around("methodCachePointcut()")  
    public Object methodCacheHold(ProceedingJoinPoint joinPoint) throws Throwable{  
        String targetName = joinPoint.getTarget().getClass().getName();  
        String methodName = joinPoint.getSignature().getName();  
        Object[] arguments = joinPoint.getArgs();  
        Object result = null;  
        @SuppressWarnings("rawtypes")
		Class targetClass = Class.forName(targetName);  
        Method[] method = targetClass.getMethods();  
        String cacheKeyTitle="";
        int expirMins = 0;  
        for(Method m:method){  
            if (m.getName().equals(methodName)) {  
                @SuppressWarnings("rawtypes")
				Class[] tmpCs = m.getParameterTypes();  
                if(tmpCs.length==arguments.length){  
                	YCacheAnno methodCache = m.getAnnotation(YCacheAnno.class);  
                	expirMins = methodCache.expirMins();  
                	cacheKeyTitle = methodCache.cacheKeyTitle();
                    break;  
                }  
            }  
        }
        String cacheKey = getCacheKey(cacheKeyTitle,targetName, methodName, arguments);  
        Object obj = EhcacheUtils.getYcache(cacheKey);
        if (obj == null) {  
            try{  
                result = joinPoint.proceed();  
            }catch(Exception e){  
                logger.info(e.toString());  
            }  
            if(result!=null){  
                try{  
                    EhcacheUtils.putValueWithYcache(cacheKey,result,expirMins);  
                }catch(Exception e){  
                    logger.info("!!!!!!!!!"+cacheKey+"!!!!!!!!!未能执行方法缓存"+e);  
                }  
            } 
            return result;
        }  
        return obj;  
    }  
  
     private String getCacheKey(String cacheKeyTitle,String targetName, String methodName,  
            Object[] arguments) {  
        StringBuffer sb = new StringBuffer();  
        sb.append(targetName).append(".").append(methodName);  
        if ((arguments != null) && (arguments.length != 0)) {  
            for (int i = 0; i < arguments.length; i++) {  
                    sb.append(".").append(arguments[i]);  
            }  
        }  
        return cacheKeyTitle+sb.toString();  
    }  
}
